﻿using log4net.Config;
using PhotoAlbum.ListViewItem;
using PhotoAlbumCS;
using smforj.common.model;
using smforj.common.service;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.UI;

namespace PhotoAlbum
{
    public partial class CustomItemFrm : Telerik.WinControls.UI.RadForm
    { 
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private string configFile = ""; 
        private int RTimeSpan = 60; 

        Thread thread_ShowInfo = null; 

        public CustomItemFrm()
        {
            InitializeComponent();
            Init();
        }
        /// <summary>
        /// 初始化参数
        /// </summary>
        private void Init()
        {
            configFile = AppDomain.CurrentDomain.BaseDirectory + @"Log.config";
            XmlConfigurator.Configure(new System.IO.FileInfo(configFile));

            //radListView1
            this.radListView1.ItemSize = new Size(200, 300);
            this.radListView1.AllowArbitraryItemHeight = true;
            this.radListView1.ItemSpacing = 10;
            this.radListView1.EnableKineticScrolling = true;

            this.radListView1.ListViewElement.ViewElement.ViewElement.Margin = new Padding(0, 10, 0, 10);
            this.radListView1.ListViewElement.ViewElement.Orientation = Orientation.Horizontal;

            this.radListView1.VisualItemCreating += radListView1_VisualItemCreating;
            //radListView2
            this.radListView2.ItemSize = new Size(200, 300);
            this.radListView2.AllowArbitraryItemHeight = true;
            this.radListView2.ItemSpacing = 10;
            this.radListView2.EnableKineticScrolling = true;

            this.radListView2.ListViewElement.ViewElement.ViewElement.Margin = new Padding(0, 10, 0, 10);
            this.radListView2.ListViewElement.ViewElement.Orientation = Orientation.Horizontal;

            this.radListView2.VisualItemCreating += radListView2_VisualItemCreating;
            //radListView3
            this.radListView3.ItemSize = new Size(200, 300);
            this.radListView3.AllowArbitraryItemHeight = true;
            this.radListView3.ItemSpacing = 10;
            this.radListView3.EnableKineticScrolling = true;

            this.radListView3.ListViewElement.ViewElement.ViewElement.Margin = new Padding(0, 10, 0, 10);
            this.radListView3.ListViewElement.ViewElement.Orientation = Orientation.Horizontal;

            this.radListView3.VisualItemCreating += radListView3_VisualItemCreating;


            //清空Text
            this.radPanel4.Text = radPanel5.Text = this.radPanel6.Text = string.Empty; 

            this.FormClosing += Form1_FormClosing;

            this.WindowState = FormWindowState.Maximized; 
            RTimeSpan = Convert.ToInt32(ConfigurationManager.AppSettings["RTimeSpan"]);

            this.timer1.Interval = 1000 * (RTimeSpan <=0 ? 60 : RTimeSpan);
        }

        private void radListView2_VisualItemCreating(object sender, ListViewVisualItemCreatingEventArgs e)
        {
            e.VisualItem = new CustomVisualItem();
        }

        private void radListView1_VisualItemCreating(object sender, ListViewVisualItemCreatingEventArgs e)
        {
            e.VisualItem = new CustomVisualItem();
        }

        void radListView3_VisualItemCreating(object sender, ListViewVisualItemCreatingEventArgs e)
        {
            e.VisualItem = new CustomVisualItem();
        } 

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //isStoped = true;
            //if (thread_ShowInfo != null)
            //{
            //    thread_ShowInfo.Abort();
            //    thread_ShowInfo = null;
            //}
        }

        private void CustomItemFrm_Load(object sender, EventArgs e)
        { 
            //显示商品类信息
            ThreadPool.QueueUserWorkItem(new WaitCallback(ShowComType));
            //显示信息 
            //thread_ShowInfo = new Thread(new ThreadStart(ThreadProcSafePost));
            //thread_ShowInfo.Start(); 

            ShowInfo(); 
            this.timer1.Enabled = true;
        }

        #region 商品类型信息
        private void ShowComType(object state)
        {
            Thread.Sleep(50);
            try
            {
                ICommodityService service = new CommodityServiceImpl();
                List<CommodityType> list = service.GetCommodityTypeList(new BaseQuery());
                list.Sort(SortByOrder);
                if (list != null && list.Count > 0)
                {
                    foreach (CommodityType type in list)
                    {
                        if (type.order == 1)
                        {
                            ShowTypeInfo(this.radPanel1,type.name);
                        }
                        else if (type.order == 2)
                        {
                            ShowTypeInfo(this.radPanel2, type.name);
                        }
                        else if (type.order == 3)
                        {
                            ShowTypeInfo(this.radPanel3, type.name);
                        }
                    }


                }
            }
            catch (Exception ex)
            {
                log.Error("显示商品类型信息异常："+ex.Message);
            }

        }

        private delegate void ShowType(RadPanel panel,String msg);

        private void ShowTypeInfo(RadPanel panel, String msg)
        {

            if (panel.IsHandleCreated && panel.InvokeRequired)
            {
                panel.Invoke(new ShowType(ShowTypeInfo), new object[] { panel, msg });
            }
            else
            {
                panel.Text = msg;
            }

        }


        private int SortByOrder(CommodityType obj1, CommodityType obj2)
        {
            int res = 0;
            if ((obj1 == null) && (obj2 == null))
            {
                return 0;
            }
            else if ((obj1 != null) && (obj2 == null))
            {
                return 1;
            }
            else if ((obj1 == null) && (obj2 != null))
            {
                return -1;
            }

            if (obj1.order > obj2.order)
            {
                res = 1;
            }
            else if (obj1.order < obj2.order)
            {
                res = -1;
            }
            return res;
        }
        #endregion



        #region 显示图片
        private IFittingService fittingService = new FittingServiceImpl();
        private Boolean isStoped = false;
        private List<Collocation> list = null;

        delegate void ShowInfoCallback(object state);

        /// <summary>
        /// 已经显示的图片信息
        /// </summary>
        private List<PhotoItem> images = new List<PhotoItem>();

        //第二步：定义线程的主体方法

        /// <summary>
        /// 线程的主体方法
        /// </summary>
        private void ThreadProcSafePost()
        {
            //...执行线程任务
            //休息10秒
            //Thread.Sleep(1000 * 2);

            //while (!isStoped)
            //{
            lock (list)
            {
                if (list == null)
                    list = fittingService.GetCollocationLocal(Program.location); 
                if (list != null && list.Count > 0)
                {
                    //在线程中更新UI（通过UI线程同步上下文m_SyncContext）
                    ShowInfo(list);
                    //...执行线程其他任务
                }
            }
            //    if (isStoped)
            //        break;
            //    //Thread.Sleep(1000 * RTimeSpan);
            //    Thread.Sleep(1000 * 10);
            //}

        }

        /// <summary>
        /// 显示信息，使用于timer
        /// </summary>
        private void ShowInfo()
        { 
            list = fittingService.GetCollocationLocal(Program.location);
            if (list != null && list.Count > 0)
            {
                //在线程中更新UI（通过UI线程同步上下文m_SyncContext）
                ShowInfo(list);
                //...执行线程其他任务
            } 
        }

        private void  ShowInfo(object state)
        {
            try
            {
                if (null != state)
                {
                    ClearItem();
                    ImageDataItem item = null;
                    List<Collocation> list = (List<Collocation>)state;
                    foreach (Collocation col in list)
                    {
                        if (col.Type == this.radPanel1.Text)
                        {
                            item = AddItem(this.radListView1, col);
                        }
                        else if (col.Type == this.radPanel2.Text)
                        { 
                            item = AddItem(this.radListView2, col); 
                        }
                        else
                        { 
                            item = AddItem(this.radListView3, col); 
                        }

                    }

                    ShowImageItem(item);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private void ClearItem()
        {
            this.radListView1.BeginInvoke((MethodInvoker)delegate() {
                this.radListView1.Items.Clear(); 
            });
            this.radListView2.BeginInvoke((MethodInvoker)delegate()
            {
                this.radListView2.Items.Clear();
            });
            this.radListView3.BeginInvoke((MethodInvoker)delegate()
            {
                this.radListView3.Items.Clear();
            });
        }
        /// <summary>
        /// 添加item
        /// </summary>
        /// <param name="rlv"></param>
        /// <param name="col"></param>
        /// <returns></returns>
        private ImageDataItem AddItem(RadListView rlv, Collocation col)
        {
            ImageDataItem item = new ImageDataItem(){
                rating = new Random().NextDouble(),
                artist = col.Name,
                title = col.ID,
                image = ImageResize(Image.FromFile(col.image), 200, 120, Color.White)
            };

            rlv.BeginInvoke((MethodInvoker)delegate()
            {
                rlv.Items.Add(item);
            });

            return item;
        }



        #endregion

        #region 图片处理
        /// <summary>
        /// Gets the closest non-indexed pixel format
        /// </summary>
        /// <param name="originalImage">Image: Original image</param>
        /// <returns>PixelFormat: Closest non-pixel image format</returns>
        public static PixelFormat GetNonIndexedPixelFormat(Image originalImage)
        {
            /*
             * These formats cause an error when creating a GDI Graphics Oblect, so must be converted to non Indexed
             * Error is "A graphics object cannot be created from an image that has an indexed pixel format"
             * 
                PixelFormat.Undefined 
                PixelFormat.DontCare 
                PixelFormat.1bppIndexed
                PixelFormat.4bppIndexed
                PixelFormat.8bppIndexed
                PixelFormat.16bppGrayScale
                PixelFormat.16bppARGB1555
             * 
             * An attempt is made to use the closest (i.e. smallest fitting) format that will hold the palette.
             */

            switch (originalImage.PixelFormat)
            {
                case PixelFormat.Undefined:
                    //This is also the same Enumation as PixelFormat.DontCare:
                    return PixelFormat.Format24bppRgb;
                case PixelFormat.Format1bppIndexed:
                    return PixelFormat.Format16bppRgb555;
                case PixelFormat.Format4bppIndexed:
                    return PixelFormat.Format16bppRgb555;
                case PixelFormat.Format8bppIndexed:
                    return PixelFormat.Format16bppRgb555;
                case PixelFormat.Format16bppGrayScale:
                    return PixelFormat.Format16bppArgb1555;
                case PixelFormat.Format32bppArgb:
                    return PixelFormat.Format24bppRgb;
                default:
                    return originalImage.PixelFormat;
            }
        }

        /// <summary>
        /// Resize image keeping aspect ratio.
        /// </summary>
        /// <param name="originalImg">Image: Image to scale</param>
        /// <param name="Width">Int: Required width in pixels</param>
        /// <param name="Height">Int: Required height in pixels</param>
        /// <param name="BackgroundColour">Color: Background colour</param>
        /// <returns>Image: Scaled Image</returns>
        public static Image ImageResize(Image originalImg, int Width, int Height, Color BackgroundColour)
        {
            int destX = 0;
            int destY = 0;

            float nPercent = 0f;

            float nPercentW = ((float)Width / (float)originalImg.Width);
            float nPercentH = ((float)Height / (float)originalImg.Height);

            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
                destX = System.Convert.ToInt16(((float)Width - ((float)originalImg.Width * nPercent)) / 2f);
            }
            else
            {
                nPercent = nPercentW;
                destY = System.Convert.ToInt16(((float)Height - ((float)originalImg.Height * nPercent)) / 2f);
            }

            int destWidth = (int)(originalImg.Width * nPercent);
            int destHeight = (int)(originalImg.Height * nPercent);

            Bitmap bmPhoto = new Bitmap(Width, Height, GetNonIndexedPixelFormat(originalImg)); // PixelFormat.Format24bppRgb);

            bmPhoto.SetResolution(originalImg.HorizontalResolution, originalImg.VerticalResolution);

            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.Clear(BackgroundColour);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;

            grPhoto.DrawImage(originalImg,
                new Rectangle(destX, destY, destWidth, destHeight),
                new Rectangle(0, 0, originalImg.Width, originalImg.Height), GraphicsUnit.Pixel);

            grPhoto.Dispose();
            return bmPhoto;
        }

        #endregion

        private void radListView1_ItemMouseClick(object sender, ListViewItemEventArgs e)
        {
            //MessageBox.Show(e.Item.ToString());
            if (e.Item  != null && e.Item is ImageDataItem)
            {
                ShowImageItem((ImageDataItem)e.Item);
            }
        }


        private void ShowImageItem(ImageDataItem item)
        {
            Image img = null;
            string remark = string.Empty;
            if (list != null)
            {
                Collocation col = list.Find(z => z.ID == item.title);
                if (col != null)
                {
                    String p = col.image.Replace(".jpg",".png");
                    if(System.IO.File.Exists(p))
                        img = Image.FromFile(p);
                    else
                        img = Image.FromFile(col.image);
                    remark = col.Remark;
                }
                else
                    img = item.image;
            }
            else
            {
                img = item.image;
            }
            this.radPanel4.BackgroundImage = img;
            this.radPanel6.Text = "粉红色的美妙之处在于它完美地展现了女人温柔、浪漫、甜美的特质，所以越来越多的女人开始尝试粉红色的装扮。像春天缓缓绽放的花儿，温婉、含蓄…… 好莱坞的女明星们穿上粉红色礼服，更加鲜亮迷人，流露高贵的女性之美。 说明,是指为了某一种用途提出的独特创意，进而把脑中的构想具体表现出来，具体来说，就是以面料做素材，以人体为对象，塑造出美的作品。 设计一词近年来出现的频率越来越高，比如：工业产品设计，工艺流程设计、广告招贴设计、服装设计、舞台美术设计等等，其意思也不一定相同，但就衣服的设计来说，是指为了某一种用途提出的独特创意，进而把脑中的构想具体表现出来，具体来说，就是以面料做素材，以人体为对象，塑造出美的作品。 　　一件成功的设计作品，不仅仅局限于观者所能看到的色彩与形态，亦指眼睛所不能看到的的作品表现方法、内部工艺等等。那些认为服装设计仅仅是画时装效果图的想法是非常片面和狭隘的。设计者不应仅仅局限于对衣服如外形、领围线、分割线等等作如何处理的构想，而应该像一位电影导演一样，立于创作的中心，统筹规划，使服装达到最完美的效果。"; //remark;
        
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            ShowInfo();                                                                         
        }

        private void radListView2_ItemMouseClick(object sender, ListViewItemEventArgs e)
        {
            //MessageBox.Show(e.Item.ToString());
            if (e.Item != null && e.Item is ImageDataItem)
            {
                ShowImageItem((ImageDataItem)e.Item);
            }
        }

        private void radListView3_ItemMouseClick(object sender, ListViewItemEventArgs e)
        {
            //MessageBox.Show(e.Item.ToString());
            if (e.Item != null && e.Item is ImageDataItem)
            {
                ShowImageItem((ImageDataItem)e.Item);
            }
        }

        private void radPanel5_MouseHover(object sender, EventArgs e)
        {
            this.radPanel5.BackgroundImage = Properties.Resources.PA_Call;
        }

        private void radPanel5_MouseLeave(object sender, EventArgs e)
        {
            this.radPanel5.BackgroundImage = Properties.Resources.PA_Call_light;
        }

        private void radPanel5_Click(object sender, EventArgs e)
        {
            MessageBox.Show("call....");
        } 
    }

}
